package com.zzr.zzrbackend.service.Impl;

import com.zzr.zzrbackend.mapper.*;
import com.zzr.zzrbackend.pojo.domain.DisabuseRecord;
import com.zzr.zzrbackend.pojo.domain.Todolist;
import com.zzr.zzrbackend.pojo.domain.User;
import com.zzr.zzrbackend.pojo.domain.UserInfo;
import com.zzr.zzrbackend.pojo.dto.CommonResult;
import com.zzr.zzrbackend.pojo.dto.param.*;
import com.zzr.zzrbackend.pojo.dto.result.*;
import com.zzr.zzrbackend.service.BEndService;
import com.zzr.zzrbackend.util.TokenUtils;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
public class BEndServiceImpl implements BEndService {
    @Resource
    private DisabuseRecordMapper disabuseRecordMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private TodolistMapper todolistMapper;
    @Resource
    VolunteerSortMapper volunteerSortMapper;

    @Override
    public CommonResult<DisabuseDataResult> getDisabuseData(HttpServletRequest request) {
        List<DisabuseRecord> disabuseRecordList = disabuseRecordMapper.selectAllDisabuseList();
        int unStart = 0;
        int solving = 0;
        int finished = 0;
        int total = disabuseRecordList.size();
        int todayAddNumber = 0;

        //解惑类型统计
        DisabuseDataTypeResult unStartType = new DisabuseDataTypeResult();
        int unStartPsychologyNumber = 0;
        int unStartStudyNumber = 0;
        int unStartInterestNumber = 0;
        int unStartEmotionNumber = 0;
        int unStartHealthNumber = 0;

        DisabuseDataTypeResult solvingType = new DisabuseDataTypeResult();
        int solvingPsychologyNumber = 0;
        int solvingStudyNumber = 0;
        int solvingInterestNumber = 0;
        int solvingEmotionNumber = 0;
        int solvingHealthNumber = 0;

        DisabuseDataTypeResult finishedType = new DisabuseDataTypeResult();
        int finishedPsychologyNumber = 0;
        int finishedStudyNumber = 0;
        int finishedInterestNumber = 0;
        int finishedEmotionNumber = 0;
        int finishedHealthNumber = 0;

        for (DisabuseRecord temp : disabuseRecordList) {
            if (temp.getIsFinish() == 0) {
                unStart++;
                if (temp.getType() == 1) {
                    unStartPsychologyNumber++;
                } else if (temp.getType() == 2) {
                    unStartStudyNumber++;
                } else if (temp.getType() == 5) {
                    unStartInterestNumber++;
                } else if (temp.getType() == 6) {
                    unStartEmotionNumber++;
                } else if (temp.getType() == 7) {
                    unStartHealthNumber++;
                }
            } else if (temp.getIsFinish() == 1) {
                solving++;
                if (temp.getType() == 1) {
                    solvingPsychologyNumber++;
                } else if (temp.getType() == 2) {
                    solvingStudyNumber++;
                } else if (temp.getType() == 5) {
                    solvingInterestNumber++;
                } else if (temp.getType() == 6) {
                    solvingEmotionNumber++;
                } else if (temp.getType() == 7) {
                    solvingHealthNumber++;
                }
            } else if (temp.getIsFinish() == 3) {
                finished++;
                if (temp.getType() == 1) {
                    finishedPsychologyNumber++;
                } else if (temp.getType() == 2) {
                    finishedStudyNumber++;
                } else if (temp.getType() == 5) {
                    finishedInterestNumber++;
                } else if (temp.getType() == 6) {
                    finishedEmotionNumber++;
                } else if (temp.getType() == 7) {
                    finishedHealthNumber++;
                }
            }

            long timestamp = temp.getTime();
            // 将时间戳转换为LocalDateTime对象
            LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());

            // 获取今天的日期
            LocalDate today = LocalDate.now();

            // 获取时间戳对应的日期
            LocalDate timestampDate = dateTime.toLocalDate();

            // 判断时间戳是否属于今天
            if (timestampDate.isEqual(today)) {
                todayAddNumber++;
            }

        }
        DisabuseDataResult disabuseDataResult = new DisabuseDataResult();
        disabuseDataResult.setUnStart(unStart);
        disabuseDataResult.setSolving(solving);
        disabuseDataResult.setFinished(finished);
        disabuseDataResult.setTotal(total);
        disabuseDataResult.setTodayAddNumber(todayAddNumber);

        List<DisabuseDataTypeResult> disabuseDataTypeResults = new ArrayList<>();
        unStartType.setHealthNumber(unStartHealthNumber);
        unStartType.setEmotionNumber(unStartEmotionNumber);
        unStartType.setInterestNumber(unStartInterestNumber);
        unStartType.setStudyNumber(unStartStudyNumber);
        unStartType.setPsychologyNumber(unStartPsychologyNumber);
        unStartType.setType("未开始");

        solvingType.setPsychologyNumber(solvingPsychologyNumber);
        solvingType.setStudyNumber(solvingStudyNumber);
        solvingType.setInterestNumber(solvingInterestNumber);
        solvingType.setEmotionNumber(solvingEmotionNumber);
        solvingType.setHealthNumber(solvingHealthNumber);
        solvingType.setType("解决中");

        finishedType.setHealthNumber(finishedHealthNumber);
        finishedType.setStudyNumber(finishedStudyNumber);
        finishedType.setEmotionNumber(finishedEmotionNumber);
        finishedType.setInterestNumber(finishedInterestNumber);
        finishedType.setPsychologyNumber(finishedPsychologyNumber);
        finishedType.setType("已完成");

        disabuseDataTypeResults.add(unStartType);
        disabuseDataTypeResults.add(solvingType);
        disabuseDataTypeResults.add(finishedType);
        disabuseDataResult.setDisabuseDataTypeResults(disabuseDataTypeResults);

        return CommonResult.success(disabuseDataResult);
    }

    @Override
    public CommonResult<ChildNumberResult> getChildNumber(HttpServletRequest request) {

        List<User> userList = userMapper.selectAllUser();
        int male = 0;
        int female = 0;
        int unknown = 0;
        for (User temp : userList) {
            if (temp.getPermission() == 1) {
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(temp.getId());
                if (userInfo != null) {
                    if (userInfo.getGender() == null) {
                        unknown++;
                    } else if (userInfo.getGender() == 0) {
                        male++;
                    } else if (userInfo.getGender() == 1) {
                        female++;
                    }
                }
            }
        }
        ChildNumberResult childNumberResult = new ChildNumberResult();
        childNumberResult.setMale(male);
        childNumberResult.setFemale(female);
        childNumberResult.setUnknown(unknown);
        return CommonResult.success(childNumberResult);
    }

    @Override
    public CommonResult<GetTodoListResult> getTodoList(GetTodoListParam getTodoListParam, HttpServletRequest request) {
        Todolist todolist = todolistMapper.selectByDate(getTodoListParam.getDate());
        if (todolist == null) {
            return CommonResult.fail("该天还未添加注意事项");
        }
        GetTodoListResult getTodoListResult = new GetTodoListResult();
        getTodoListResult.setTheme(todolist.getTheme());

        return CommonResult.success(getTodoListResult);
    }

    @Override
    public CommonResult<NoData> addTodoList(AddTodoListParam addTodoListParam, HttpServletRequest request) {

        Todolist todolist = todolistMapper.selectByDate(addTodoListParam.getDate());
        if (todolist != null) {
            return CommonResult.fail("当天已添加注意事项");
        }

        int i = todolistMapper.insert(addTodoListParam.getDate(), addTodoListParam.getTheme());
        if (i != 1) {
            return CommonResult.fail("插入数据库异常");
        }

        return CommonResult.success();
    }

    @Override
    public CommonResult<ShowDisabuseListResult> showDisabuseList(HttpServletRequest request) {

        List<DisabuseRecord> disabuseRecordList = disabuseRecordMapper.selectAllDisabuseList();
        List<ShowDisabuseResult> showDisabuseResultList = new ArrayList<>();

        ShowDisabuseResult Psychology = getData(1, disabuseRecordList);
        Psychology.setType("心理");
        showDisabuseResultList.add(Psychology);

        ShowDisabuseResult Study = getData(2, disabuseRecordList);
        Study.setType("学习");
        showDisabuseResultList.add(Study);

        ShowDisabuseResult Interest = getData(5, disabuseRecordList);
        Interest.setType("兴趣");
        showDisabuseResultList.add(Interest);

        ShowDisabuseResult Emotion = getData(6, disabuseRecordList);
        Emotion.setType("感情");
        showDisabuseResultList.add(Emotion);

        ShowDisabuseResult Health = getData(7, disabuseRecordList);
        Health.setType("健康");
        showDisabuseResultList.add(Health);

        ShowDisabuseListResult showDisabuseListResult = new ShowDisabuseListResult();
        showDisabuseListResult.setShowDisabuseResultList(showDisabuseResultList);
        return CommonResult.success(showDisabuseListResult);
    }

    @Override
    public CommonResult<NoData> personalCenter(PersonalCenterParam personalCenterParam, HttpServletRequest request) {
        Claims claims = TokenUtils.getClaimsFromJwt(request.getHeader("Token"));
        Integer userId = (Integer) claims.get("id");
        User user = userMapper.selectById(userId);
        PersonalCenterBParam volunteer = new PersonalCenterBParam();

        volunteer.setGender(personalCenterParam.getGender());
        volunteer.setNativePlace(personalCenterParam.getNativePlace());
        volunteer.setAge(personalCenterParam.getAge());
        volunteer.setSign(personalCenterParam.getSign());
        volunteer.setGoodSolveProblems(personalCenterParam.getGoodSolveProblems().toString());
        try {
            if (user.getIsCertification() == 0) {
                userMapper.updateByCertification(userId);
                userInfoMapper.setVolunteer(userId, volunteer);
                volunteerSortMapper.init(userId);
            } else {
                userInfoMapper.setVolunteer(userId, volunteer);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.fail();
        }

        return CommonResult.success();
    }

    @Override
    public CommonResult<NoData> modifyName(ModifyNameParam modifyNameParam, HttpServletRequest request) {
        Claims claims = TokenUtils.getClaimsFromJwt(request.getHeader("Token"));
        Integer userId = (Integer) claims.get("id");
        User user = userMapper.selectById(userId);
        if (user == null) {
            return CommonResult.fail("数据库异常");
        }
        int i = userMapper.updateUserName(userId, modifyNameParam.getName());
        if (i != 1) {
            return CommonResult.fail("用户名更新失败");
        }
        int j = userInfoMapper.updateName(userId, modifyNameParam.getName());
        if (j != 1) {
            return CommonResult.fail("用户名更新失败");
        }

        return CommonResult.success();
    }

    @Override
    public CommonResult<NoData> modifyPhone(ModifyPhoneParam modifyPhoneParam, HttpServletRequest request) {
        Claims claims = TokenUtils.getClaimsFromJwt(request.getHeader("Token"));
        Integer userId = (Integer) claims.get("id");
        User user = userMapper.selectById(userId);
        if (user == null) {
            return CommonResult.fail("数据库异常");
        }
        int i = userMapper.updatePhone(userId, modifyPhoneParam.getPhone());
        if (i != 1) {
            return CommonResult.fail("手机号更新失败");
        }

        return CommonResult.success();
    }

    public ShowDisabuseResult getData(Integer type, List<DisabuseRecord> disabuseRecordList) {
        ShowDisabuseResult ShowDisabuseResult = new ShowDisabuseResult();

        Instant now = Instant.now(); // 当前时间
        System.out.println(now);
        Instant sevenDaysAgo = now.minusSeconds(6 * 24 * 60 * 60); // 七天前的时间
        System.out.println(sevenDaysAgo);
        Instant sixDaysAgo = now.minusSeconds(5 * 24 * 60 * 60); // 六天前的时间
        Instant fiveDaysAgo = now.minusSeconds(4 * 24 * 60 * 60); // 五天前的时间
        Instant fourDaysAgo = now.minusSeconds(3 * 24 * 60 * 60); // 四天前的时间
        Instant threeDaysAgo = now.minusSeconds(2 * 24 * 60 * 60); // 三天前的时间
        Instant towDaysAgo = now.minusSeconds(24 * 60 * 60); // 二天前的时间
        Instant oneDaysAgo = now.minusSeconds(60 * 60); // 一天前的时间

        int seven = 0;
        int six = 0;
        int five = 0;
        int four = 0;
        int three = 0;
        int tow = 0;
        int one = 0;

        for (DisabuseRecord temp : disabuseRecordList) {
            if (Objects.equals(temp.getType(), type)) {
                Long timestamp = temp.getTime();
                Instant instant = Instant.ofEpochSecond(timestamp);
                if (instant.isAfter(oneDaysAgo) && instant.isBefore(now)) {
                    one++;
                } else if (instant.isAfter(towDaysAgo) && instant.isBefore(now)) {
                    tow++;
                } else if (instant.isAfter(threeDaysAgo) && instant.isBefore(now)) {
                    three++;
                } else if (instant.isAfter(fourDaysAgo) && instant.isBefore(now)) {
                    four++;
                } else if (instant.isAfter(fiveDaysAgo) && instant.isBefore(now)) {
                    five++;
                } else if (instant.isAfter(sixDaysAgo) && instant.isBefore(now)) {
                    six++;
                } else if (instant.isAfter(sevenDaysAgo) && instant.isBefore(now)) {
                    seven++;
                }
            }
        }
        List<Integer> list = new ArrayList<>();
        list.add(seven);
        list.add(six);
        list.add(five);
        list.add(four);
        list.add(three);
        list.add(tow);
        list.add(one);
        ShowDisabuseResult.setList(list);


        return ShowDisabuseResult;
    }
}
